package com.example.core.filter.auth;

import com.example.common.enums.ResponseCode;
import com.example.common.exception.ResponseException;
import com.example.core.context.GatewayContext;
import com.example.core.filter.Filter;
import com.example.core.filter.FilterAspect;
import io.jsonwebtoken.Jwt;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.impl.DefaultClaims;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import static com.example.common.constants.FilterConst.*;

/**
 * @Author Peng Yisheng
 * @Date 2024/12/9 17:13
 * @Description 用户鉴权过滤器：JWT实现
 */
@Slf4j
@FilterAspect(id = USER_AUTH_FILTER_ID,
        name = USER_AUTH_FILTER_NAME,
        order = USER_AUTH_FILTER_ORDER)
public class UserAuthFilter implements Filter {
    private static final String SECRET_KEY = "api-gateway";  // JWT加密密钥

    private static final String COOKIE_NAME = "user-auth-jwt";  // 存放JWT token信息的cookie name

    @Override
    public void doFilter(GatewayContext ctx) throws Exception {
        // 检查规则是否配置了需要用户鉴权
        if (ctx.getRule().getFilterConfig(USER_AUTH_FILTER_ID) == null) {
            return;
        }

        if (ctx.getRequest().getCookie(COOKIE_NAME) == null) {
            throw new ResponseException(ResponseCode.UNAUTHORIZED);
        }

        String token = ctx.getRequest().getCookie(COOKIE_NAME).value();
        if (StringUtils.isBlank(token)) {
            throw new ResponseException(ResponseCode.UNAUTHORIZED);
        }

        // JWT生成token，以及解析token；com.example.core.filter.auth.JwtTest
        try {
            // 解析用户id
            Jwt jwt = Jwts.parser().setSigningKey(SECRET_KEY).parse(token);
            long userId = Long.parseLong(((DefaultClaims) jwt.getBody()).getSubject());
            log.info("auth passed, userid={}", userId);
            // 把用户id传给下游
            ctx.getRequest().setUserId(userId);
        } catch (Exception e) {
            throw new ResponseException(ResponseCode.UNAUTHORIZED);
        }
    }

}
